using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Outpatient.Doman.Smart;
using Outpatient.ErrorCode;
using Outpatient.Infrastructure;
using OutpatientApi.DTO;
using OutpatientApi.Methodimplementation.IServices;

namespace OutpatientApi.Methodimplementation.Services
{
    /// <summary>
    /// 咨询分类服务实现类
    /// </summary>
    public class ConsultationCategoryService : IConsultationCategoryService
    {
        private readonly EFDbContext _context;
        private readonly ILogger<ConsultationCategoryService> _logger;
        private readonly IBaseRepository<DoctorInfo> doctorInfo;
        private readonly IBaseRepository<ConsultationDetail> consultationDetail;
        private readonly IBaseRepository<PriceItem> priceItem;
        private readonly IBaseRepository<Discount> discount;
        private readonly IBaseRepository<Guide> guide;
        private readonly IBaseRepository<UserCollection> userCollection;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        /// <param name="doctorInfo">医生信息仓储</param>
        /// <param name="consultationDetail">咨询详情仓储</param>
        /// <param name="priceItem">价目表仓储</param>
        /// <param name="discount">优惠活动仓储</param>
        /// <param name="guide">就医指南仓储</param>
        /// <param name="userCollection">用户收藏仓储</param>
        public ConsultationCategoryService(EFDbContext context, ILogger<ConsultationCategoryService> logger,IBaseRepository<DoctorInfo> doctorInfo,IBaseRepository<ConsultationDetail> consultationDetail, IBaseRepository<PriceItem> priceItem, IBaseRepository<Discount> discount, IBaseRepository<Guide> guide, IBaseRepository<UserCollection> userCollection)
        {
            _context = context;
            _logger = logger;
            this.doctorInfo = doctorInfo;
            this.consultationDetail = consultationDetail;
            this.priceItem = priceItem;
            this.discount = discount;
            this.guide = guide;
            this.userCollection = userCollection;
        }

        /// <summary>
        /// 获取所有咨询分类
        /// </summary>
        /// <returns>咨询分类列表</returns>
        public async Task<ApiResult<List<ConsultationCategoryDto>>> GetAllCategoriesAsync()
        {
            try
            {
                _logger.LogInformation("开始获取所有咨询分类");

                var categories = await _context.ConsultationCategory
                    .Where(c => !c.IsDeleted)
                    .Include(c => c.Consultations.Where(con => !con.IsDeleted))
                    .Select(c => new ConsultationCategoryDto
                    {
                        CategoryId = c.CategoryId,
                        CategoryName = c.CategoryName,
                        Icon = c.Icon,
                        Description = c.Description,
                        CreateTime = c.CreateTime,
                        ConsultationCount = c.Consultations.Count
                    })
                    .ToListAsync();

                _logger.LogInformation("成功获取咨询分类，共 {Count} 个分类", categories.Count);

                var result = new ApiResult<List<ConsultationCategoryDto>>();
                result.success(categories, "获取咨询分类成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有咨询分类时发生异常");
                return new ApiResult<List<ConsultationCategoryDto>> { msg = "获取咨询分类失败" };
            }
        }

        /// <summary>
        /// 根据分类ID获取咨询信息列表
        /// </summary>
        /// <param name="categoryId">分类ID</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">页大小</param>
        /// <returns>咨询信息列表</returns>
        public async Task<ApiResult<List<ConsultationDto>>> GetConsultationsByCategoryIdAsync(int categoryId, int pageIndex = 1, int pageSize = 10)
        {
            try
            {
                _logger.LogInformation("开始根据分类ID获取咨询信息，分类ID：{CategoryId}，页码：{PageIndex}，页大小：{PageSize}", 
                    categoryId, pageIndex, pageSize);

                // 验证分类是否存在
                var categoryExists = await _context.ConsultationCategory
                    .AnyAsync(c => c.CategoryId == categoryId && !c.IsDeleted);

                if (!categoryExists)
                {
                    _logger.LogWarning("分类不存在，分类ID：{CategoryId}", categoryId);
                    return new ApiResult<List<ConsultationDto>> { msg = "分类不存在" };
                }

                var consultations = await _context.Consultation
                    .Where(c => c.CategoryId == categoryId && !c.IsDeleted)
                    .Include(c => c.Category)
                    .Include(c => c.ConsultationDetails.Where(cd => !cd.IsDeleted))
                    .Select(c => new ConsultationDto
                    {
                        ConsultId = c.ConsultId,
                        Title = c.Title,
                        Content = c.Content,
                        CategoryId = c.CategoryId,
                        CategoryName = c.Category.CategoryName,
                        Keywords = c.Keywords,
                        ViewCount = c.ViewCount,
                        LikeCount = c.LikeCount,
                        CreatedAt = c.CreatedAt,
                        UpdatedAt = c.UpdatedAt,
                        Status = c.Status,
                        DetailCount = c.ConsultationDetails.Count
                    })
                    .OrderByDescending(c => c.CreatedAt)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize)
                    .ToListAsync();

                _logger.LogInformation("成功获取咨询信息，分类ID：{CategoryId}，返回 {Count} 条记录", 
                    categoryId, consultations.Count);

                var result = new ApiResult<List<ConsultationDto>>();
                result.success(consultations, "获取咨询信息成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据分类ID获取咨询信息时发生异常，分类ID：{CategoryId}", categoryId);
                return new ApiResult<List<ConsultationDto>> { msg = "获取咨询信息失败" };
            }
        }
        /// <summary>
        /// 根据健康咨询ID获取咨询详情信息列表
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<List<ConsultationDetailDto>>> SearchConsultationDetail(ParameterConsultationDetailDto dto)
        {
            try
            {
                _logger.LogInformation("操作成功");
                var res=new ApiResult<List<ConsultationDetailDto>>();


                var consultationDetailinfo = consultationDetail.Getlist().Where(x => x.IsDeleted.Equals(false)&&x.ConsultId.Equals(dto.ConsultId));
                var doctorInfoinfo= doctorInfo.Getlist().Where(x=>x.IsDeleted.Equals(false));


                var linp = from a in consultationDetailinfo
                           join b in doctorInfoinfo on a.DoctorId equals b.DoctorId
                           select new ConsultationDetailDto()
                           {
                               DetailId=a.DetailId,
                               ConsultId=a.ConsultId,
                               DoctorId=a.DoctorId,
                               Response=a.Response,
                               MedicalKnowledgeLink=a.MedicalKnowledgeLink,
                               CreateTime=a.CreateTime,
                               IsDeleted=a.IsDeleted,
                               Name=b.Name,
                               Gender=b.Gender,
                               DepartmentId=b.DepartmentId,
                               Title=b.Title

                           };

                res.success(linp.ToList(), "成功根据健康咨询ID获取咨询详情信息列表");
                return res;



            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有咨询详情时发生异常");
                throw;
            }
        }

        /// <summary>
        /// 查询价目表信息（支持按标题和标签查找）
        /// </summary>
        /// <param name="dto">查询参数</param>
        /// <returns>价目表信息列表</returns>
        public async Task<ApiResult<List<PriceItemDto>>> SearchPriceItemsAsync(PriceItemQueryDto dto)
        {
            try
            {
                _logger.LogInformation("开始查询价目表信息，标题：{Title}，标签：{Tag}，页码：{PageIndex}，页大小：{PageSize}", 
                    dto.Title, dto.Tag, dto.PageIndex, dto.PageSize);

                var query = _context.PriceItem
                    .Where(p => !p.IsDeleted)
                    .Include(p => p.Department)
                    .AsQueryable();

                // 按标题查询
                if (!string.IsNullOrWhiteSpace(dto.Title))
                {
                    query = query.Where(p => p.Title.Contains(dto.Title) || p.ServiceName.Contains(dto.Title));
                }

                // 按标签查询
                if (!string.IsNullOrWhiteSpace(dto.Tag))
                {
                    query = query.Where(p => p.Tag.Contains(dto.Tag));
                }

                // 分页查询
                var totalCount = await query.CountAsync();
                var priceItems = await query
                    .Select(p => new PriceItemDto
                    {
                        PriceId = p.PriceId,
                        ServiceName = p.ServiceName,
                        ServiceType = p.ServiceType,
                        DepartmentId = p.DepartmentId,
                        DepartmentName = p.Department != null ? p.Department.DepartmentName : null,
                        DoctorLevel = p.DoctorLevel,
                        Price = p.Price,
                        Currency = p.Currency,
                        ValidFrom = p.ValidFrom,
                        Title = p.Title,
                        Tag = p.Tag,
                        Sample = p.Sample
                    })
                    .OrderByDescending(p => p.ValidFrom)
                    .Skip((dto.PageIndex - 1) * dto.PageSize)
                    .Take(dto.PageSize)
                    .ToListAsync();

                _logger.LogInformation("成功查询价目表信息，共 {TotalCount} 条记录，返回 {Count} 条记录", 
                    totalCount, priceItems.Count);

                var result = new ApiResult<List<PriceItemDto>>();
                result.success(priceItems, $"查询价目表信息成功，共找到 {totalCount} 条记录");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询价目表信息时发生异常，标题：{Title}，标签：{Tag}", dto.Title, dto.Tag);
                return new ApiResult<List<PriceItemDto>> { msg = "查询价目表信息失败" };
            }
        }

        /// <summary>
        /// 查询优惠活动信息（支持与价目表连查）
        /// </summary>
        /// <param name="dto">查询参数</param>
        /// <returns>优惠活动信息列表</returns>
        public async Task<ApiResult<List<DiscountDto>>> SearchDiscountsAsync(DiscountQueryDto dto)
        {
            try
            {
                _logger.LogInformation("开始查询优惠活动信息，名称：{Name}，价目表标题：{PriceTitle}，页码：{PageIndex}，页大小：{PageSize}", 
                    dto.Name, dto.PriceTag, dto.PageIndex, dto.PageSize);

                var query = _context.Discount
                    .Where(d => !d.IsDeleted)
                    .Include(d => d.PriceItem)
                    .AsQueryable();

                // 按优惠活动名称查询
                if (!string.IsNullOrWhiteSpace(dto.Name))
                {
                    query = query.Where(d => d.Name.Contains(dto.Name));
                }

                // 按价目表标题查询
                if (!string.IsNullOrWhiteSpace(dto.PriceTag))
                {
                    query = query.Where(d => d.PriceItem != null && 
                        (d.PriceItem.Tag.Contains(dto.PriceTag) || 
                         d.PriceItem.ServiceName.Contains(dto.PriceTag)));
                }

                // 分页查询
                var totalCount = await query.CountAsync();
                var discounts = await query
                    .Select(d => new DiscountDto
                    {
                        DiscountId = d.DiscountId,
                        Name = d.Name,
                        Description = d.Description,
                        Rule = d.Rule,
                        PriceId = d.PriceId,
                        ValidFrom = d.ValidFrom,
                        ValidTo = d.ValidTo,
                        PriceServiceName = d.PriceItem != null ? d.PriceItem.ServiceName : null,
                        PriceTitle = d.PriceItem != null ? d.PriceItem.Title : null,
                        PriceServiceType = d.PriceItem != null ? d.PriceItem.ServiceType : null,
                        PriceAmount = d.PriceItem != null ? d.PriceItem.Price : null,
                        PriceCurrency = d.PriceItem != null ? d.PriceItem.Currency : null,
                        PriceTag = d.PriceItem != null ? d.PriceItem.Tag : null,
                        Title=d.PriceItem!=null?d.PriceItem.Title:null
                    })
                    .OrderByDescending(d => d.ValidFrom)
                    .Skip((dto.PageIndex - 1) * dto.PageSize)
                    .Take(dto.PageSize)
                    .ToListAsync();

                _logger.LogInformation("成功查询优惠活动信息，共 {TotalCount} 条记录，返回 {Count} 条记录", 
                    totalCount, discounts.Count);

                var result = new ApiResult<List<DiscountDto>>();
                result.success(discounts, $"查询优惠活动信息成功，共找到 {totalCount} 条记录");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询优惠活动信息时发生异常，名称：{Name}，价目表标题：{PriceTitle}", dto.Name, dto.PriceTag);
                return new ApiResult<List<DiscountDto>> { msg = "查询优惠活动信息失败" };
            }
        }

        /// <summary>
        /// 获取所有就医指南信息
        /// </summary>
        /// <returns>就医指南信息列表</returns>
        public async Task<ApiResult<List<GuideDto>>> GetAllGuidesAsync()
        {
            try
            {
                _logger.LogInformation("开始获取所有就医指南信息");

                var guides = await _context.Guide
                    .Include(g => g.Hospital)
                    .Select(g => new GuideDto
                    {
                        GuideId = g.GuideId,
                        Title = g.Title,
                        Content = g.Content,
                        HospitalId = g.HospitalId,
                        HospitalName = g.Hospital != null ? g.Hospital.Name : null,
                        Steps = g.Steps,
                        Views = g.Views,
                        CreatedAt = g.CreatedAt,
                        UpdatedAt = g.UpdatedAt
                    })
                    .OrderByDescending(g => g.CreatedAt)
                    .ToListAsync();

                _logger.LogInformation("成功获取就医指南信息，共 {Count} 条记录", guides.Count);

                var result = new ApiResult<List<GuideDto>>();
                result.success(guides, "获取就医指南信息成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有就医指南信息时发生异常");
                return new ApiResult<List<GuideDto>> { msg = "获取就医指南信息失败" };
            }
        }

        /// <summary>
        /// 根据指南ID获取指南详情
        /// </summary>
        /// <param name="guideId">指南ID</param>
        /// <returns>指南详情</returns>
        public async Task<ApiResult<GuideDto>> GetGuideByIdAsync(int guideId)
        {
            try
            {
                _logger.LogInformation("开始根据指南ID获取指南详情，指南ID：{GuideId}", guideId);

                var guide = await _context.Guide
                    .Include(g => g.Hospital)
                    .Where(g => g.GuideId == guideId)
                    .Select(g => new GuideDto
                    {
                        GuideId = g.GuideId,
                        Title = g.Title,
                        Content = g.Content,
                        HospitalId = g.HospitalId,
                        HospitalName = g.Hospital != null ? g.Hospital.Name : null,
                        Steps = g.Steps,
                        Views = g.Views,
                        CreatedAt = g.CreatedAt,
                        UpdatedAt = g.UpdatedAt
                    })
                    .FirstOrDefaultAsync();

                if (guide == null)
                {
                    _logger.LogWarning("指南不存在，指南ID：{GuideId}", guideId);
                    return new ApiResult<GuideDto> { msg = "指南不存在" };
                }

                _logger.LogInformation("成功获取指南详情，指南ID：{GuideId}，标题：{Title}", guideId, guide.Title);

                var result = new ApiResult<GuideDto>();
                result.success(guide, "获取指南详情成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据指南ID获取指南详情时发生异常，指南ID：{GuideId}", guideId);
                return new ApiResult<GuideDto> { msg = "获取指南详情失败" };
            }
        }

        /// <summary>
        /// 新增用户收藏
        /// </summary>
        /// <param name="dto">新增收藏参数</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult<bool>> AddUserCollectionAsync(AddUserCollectionDto dto)
        {
            try
            {
                _logger.LogInformation("开始新增用户收藏，用户ID：{UserId}，指南ID：{GuideId}，项目类型：{ItemType}", 
                    dto.UserId, dto.GuideId, dto.ItemType);

                // 验证用户是否存在
                var userExists = await _context.Users.AnyAsync(u => u.UserId == dto.UserId);
                if (!userExists)
                {
                    _logger.LogWarning("用户不存在，用户ID：{UserId}", dto.UserId);
                    return new ApiResult<bool> { msg = "用户不存在" };
                }

                // 验证指南是否存在
                var guideExists = await _context.Guide.AnyAsync(g => g.GuideId == dto.GuideId);
                if (!guideExists)
                {
                    _logger.LogWarning("指南不存在，指南ID：{GuideId}", dto.GuideId);
                    return new ApiResult<bool> { msg = "指南不存在" };
                }

                // 检查是否已经收藏过
                var existingCollection = await _context.UserCollection
                    .AnyAsync(uc => uc.UserId == dto.UserId && uc.GuideId == dto.GuideId && uc.ItemType == dto.ItemType);
                
                if (existingCollection)
                {
                    _logger.LogWarning("用户已收藏该项目，用户ID：{UserId}，指南ID：{GuideId}", dto.UserId, dto.GuideId);
                    return new ApiResult<bool> { msg = "您已经收藏过该项目" };
                }

                // 创建新的收藏记录
                var newCollection = new UserCollection
                {
                    UserId = dto.UserId,
                    GuideId = dto.GuideId,
                    ItemType = dto.ItemType,
                    CreatedAt = DateTime.Now
                };

                // 添加到数据库
                await _context.UserCollection.AddAsync(newCollection);
                await _context.SaveChangesAsync();

                _logger.LogInformation("成功新增用户收藏，用户ID：{UserId}，指南ID：{GuideId}", dto.UserId, dto.GuideId);

                var result = new ApiResult<bool>();
                result.success(true, "收藏成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "新增用户收藏时发生异常，用户ID：{UserId}，指南ID：{GuideId}", dto.UserId, dto.GuideId);
                return new ApiResult<bool> { msg = "收藏失败" };
            }
        }

        /// <summary>
        /// 检查用户是否已收藏指定项目
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="guideId">指南ID</param>
        /// <param name="itemType">项目类型</param>
        /// <returns>是否已收藏</returns>
        public async Task<ApiResult<bool>> CheckUserCollectionAsync(int userId, int guideId, string itemType)
        {
            try
            {
                _logger.LogInformation("开始检查用户收藏状态，用户ID：{UserId}，指南ID：{GuideId}，项目类型：{ItemType}", 
                    userId, guideId, itemType);

                var isCollected = await _context.UserCollection
                    .AnyAsync(uc => uc.UserId == userId && uc.GuideId == guideId && uc.ItemType == itemType);

                _logger.LogInformation("用户收藏状态检查完成，用户ID：{UserId}，指南ID：{GuideId}，已收藏：{IsCollected}", 
                    userId, guideId, isCollected);

                var result = new ApiResult<bool>();
                result.success(isCollected, "检查收藏状态成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查用户收藏状态时发生异常，用户ID：{UserId}，指南ID：{GuideId}", userId, guideId);
                return new ApiResult<bool> { msg = "检查收藏状态失败" };
            }
        }

        /// <summary>
        /// 取消用户收藏
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="guideId">指南ID</param>
        /// <param name="itemType">项目类型</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult<bool>> RemoveUserCollectionAsync(int userId, int guideId, string itemType)
        {
            try
            {
                _logger.LogInformation("开始取消用户收藏，用户ID：{UserId}，指南ID：{GuideId}，项目类型：{ItemType}", 
                    userId, guideId, itemType);

                var collection = await _context.UserCollection
                    .FirstOrDefaultAsync(uc => uc.UserId == userId && uc.GuideId == guideId && uc.ItemType == itemType);

                if (collection == null)
                {
                    _logger.LogWarning("收藏记录不存在，用户ID：{UserId}，指南ID：{GuideId}", userId, guideId);
                    return new ApiResult<bool> { msg = "您还没有收藏该项目" };
                }

                // 删除收藏记录
                _context.UserCollection.Remove(collection);
                await _context.SaveChangesAsync();

                _logger.LogInformation("成功取消用户收藏，用户ID：{UserId}，指南ID：{GuideId}", userId, guideId);

                var result = new ApiResult<bool>();
                result.success(true, "取消收藏成功");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "取消用户收藏时发生异常，用户ID：{UserId}，指南ID：{GuideId}", userId, guideId);
                return new ApiResult<bool> { msg = "取消收藏失败" };
            }
        }
    }
} 